三分钟基础:杀死进程的N种姿势你知道吗
The following article is from 编程珠玑 Author 守望先生
来源:公众号【编程珠玑】
作者:守望先生
你是如何终止你的程序的?在《killall为什么找不到你的进程》一文中提到了几个杀死进程的方法,本文来总结一下有哪些方法可以终止进程。
ctrl+c
没错,这应该是你最常用到的方法了,当前终端非后台运行一个程序后,使用ctrl+c
即可终止当前程序。
ctrl+z
这种方式不算完全终止,更像是暂停,因为它可以通过fg或者bg继续执行。
举个例子,代码如下:
//test.c
//来源:公众号【编程珠玑】
int main(void)
{
int i = 0;
for(i = 0;i < 100;i++)
{
printf("%d\n",i);
sleep(1);
}
return 0;
}
编译运行到一定程序后,按下ctrl+z:
$ gcc -o test test.c
$ ./test
0
1
2
^Z
[1]+ Stopped ./hello
root@ubuntu16:c$ fg
./hello
3
4
5
root@ubuntu16:c$
在ctrl+z之后,再输入fg或者bg,你会发现它接着上次的地方继续运行。
kill
这是最常见也是最常用的了,虽然它名为kill,但实际上它可以给进程发送各种类型的信号,其中信号9就是比较常用的,即用来终止进程。
kill -9 pid
kill用于给进程发信号,上面的命令表示给进程id为pid的程序发送9信号。
常见信号如下:
HUP 1 终端断线
INT 2 中断(同 Ctrl + C)
QUIT 3 退出(同 Ctrl + \)
TERM 15 终止
KILL 9 强制终止
CONT 18 继续(与STOP相反, fg/bg命令)
可以看到信号KILL就是强制终止程序。
你也可以通过这样来查看这些数字的意义:
kill -l 9
KILL
kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
killall
killall进程杀死进程,它在某些情况下会失效,具体可以参考《killall为什么找不到你的进程》
它还支持杀死一定时间的进程,例如杀死运行超过30分钟的hello进程:
$ killall -o 30m hello
其中-o表示older-than,当然你还可以用-y,表示yonger-than。
m表示分钟,还有其他的时间刻度:
s 秒
m 分钟
h 小时
d 天
w 周
M 月
y 年
它除了可以根据名字还可以根据正则表达式来杀死进程。使用-r参数即可。
pkill
pkill也可以根据进程名杀死进程,它和killall有点类似。
$ pkill hello
由于你可能起了多个hello程序,所以为了杀死最旧的进程,你可以这样做:
$ pkill -o hello #oldest
或者杀死最新的进程:
$ pkill -n hello #newest
或者计算运行的hello程序的数量:
$ pkill -c hello
如何查找进程id
上面提到的有些命令需要根据pid进行操作,如何获取pid呢?也有几种常见的方法。
ps
这是最常见的的了,可以参考《ps命令实例详解》
pidof
pidof可以直接获取某个进程的进程id,也比较准确:
$ pidof hello
7584
结合kill可以这样用:
$ kill -9 `pidof hello`
是不是一气呵成?
pgrep
它同样可以通过名字直接获取到进程id:
$ pgrep hello
19971
24770
top
top 的结果中也可以看到各个进程的进程id。
总结
本文仅对一些常见终止进程方式进行简单介绍,更多用法可以参考对应手册。
但是这些操作都有着同样的本质,那就是给进程发送信号,而进程通常对这个信号的处理是终止程序或者被迫终止。所以如果你想要实现优雅退出,可以试着给进程发特定信号,在收到该信号后,进程做善后处理,然后退出。
推荐阅读